<?php
use Carbon\Carbon;
use Illuminate\Support\Facades\Redis;
/* 修改env文件

 //你可以更新你想要的任何值 key => value 
$data = [
 'APP_ENV' => 'your_environment',
 'APP_KEY' => 'your_key',
 'APP_DEBUG' => 'trueOrFalse',
 'DB_DATABASE' => 'test',
 'DB_USERNAME' => 'test',
 'DB_PASSWORD' => 'test',
 'DB_HOST' => 'localhost',
 'CACHE_DRIVER' => 'file',
 'SESSION_DRIVER' => 'file',
];
// 或者
$data = [
 'DB_HOST' => '127.0.0.1',
];
*/
if (!function_exists('modifyEnv')) {
  function modifyEnv(array $data) 
  {
   $envPath = base_path() . DIRECTORY_SEPARATOR . '.env';
   
   $contentArray = collect(file($envPath, FILE_IGNORE_NEW_LINES));
   
   $contentArray->transform(function ($item) use ($data){
     foreach ($data as $key => $value){
      if(\Str::contains($item, $key)){
       return $key . '=' . $value;
      }
     }
   
     return $item;
    });
   
   $content = implode( "\n",$contentArray->toArray());
   
   \File::put($envPath, $content);
  }
}

/**
 *      把秒数转换为时分秒的格式
 *      @param Int $times 时间，单位 秒
 *      @return String
 */ 
function secToTime($times){ 
    $result = '00:00:00'; 
    if ($times>0) { 
            $hour = floor($times/3600); 
            $minute = floor(($times-3600 * $hour)/60); 
            $second = floor((($times-3600 * $hour) - 60 * $minute) % 60); 
            $result = $hour.':'.$minute.':'.$second; 
    } 
    return $result; 
}
/**
* 格式化特殊字符串等
* @param  $strParam         需要格式化的参数
* @return string            格式化结果
 */
 
function replaceSpecialChar($strParam)
{
    $regex = "/\/|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\+|\{|\}|\:|\<|\>|\?|\[|\]|\,|\.|\/|\;|\'|\`|\-|\=|\\\|\|/";
    return preg_replace($regex, "", $strParam);
 
}
 
/**
* 格式化字节大小
* @param  number $size      字节数
* @param  string $delimiter 数字和单位分隔符
* @return string            格式化后的带单位的大小
 */
function get_byte($size, $delimiter = '') {
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}
 
/**
 * 产生随机字符串
 *
 * @param    int        $length  输出长度
 * @param    string     $chars   可选的 ，默认为 0123456789
 * @return   string     字符串
 */
function get_random($length, $chars = '0123456789') {
    $hash = '';
    $max = strlen($chars) - 1;
    for($i = 0; $i < $length; $i++) {
        $hash .= $chars[mt_rand(0, $max)];
    }
    return $hash;
}
 

 
/**
 * 反字符 去标签 自动加点 去换行 截取字符串
 */
function cutstr ($data, $no, $le = '') {
    $data = strip_tags(htmlspecialchars_decode($data));
    $data = str_replace(array("\r\n", "\n\n", "\r\r", "\n", "\r"), '', $data);
    $datal = strlen($data);
    $str = msubstr($data, 0, $no);
    $datae = strlen($str);
    if ($datal > $datae)
        $str .= $le;
    return $str;
}
 
 
/**
 * 将一个字符串转换成数组，支持中文
 * @param string    $string   待转换成数组的字符串
 * @return string   转换后的数组
 */
function strToArray($string) {
    $strlen = mb_strlen($string);
    while ($strlen) {
        $array[] = mb_substr($string, 0, 1, "utf8");
        $string = mb_substr($string, 1, $strlen, "utf8");
        $strlen = mb_strlen($string);
    }
    return $array;
}
 
 
 
 
/**
* 对查询结果集进行排序
* @access public
* @param array $list 查询结果
* @param string $field 排序的字段名
* @param array $sortby 排序类型
* asc正向排序 desc逆向排序 nat自然排序
* @return array
*/
function list_sort_by($list,$field, $sortby='asc') {
   if(is_array($list)){
       $refer = $resultSet = array();
       foreach ($list as $i => $data)
           $refer[$i] = &$data[$field];
       switch ($sortby) {
           case 'asc': // 正向排序
                asort($refer);
                break;
           case 'desc':// 逆向排序
                arsort($refer);
                break;
           case 'nat': // 自然排序
                natcasesort($refer);
                break;
       }
       foreach ( $refer as $key=> $val)
           $resultSet[] = &$list[$key];
       return $resultSet;
   }else{
    return false;
   }
}
 
 
// 获取客户端IP
if (!function_exists('getIp')) {
    function getIp($ip2long = false)
    {
        $ip = '';
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos = array_search('unknown', $arr);
            if (false !== $pos) unset($arr[$pos]);
            $ip = trim($arr[0]);
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        if (!empty($ip) && $ip2long) $ip = bindec(decbin(ip2long($ip)));
        return $ip;
    }
}
 
 
// curl 请求
if (!function_exists('curlRequest')) {
    function curlRequest($url, $data = [], $headers = [], $timeout = 10, $method = 'GET')
    {
        $curl = curl_init();
        if (!empty($headers)) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }
 
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
 
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
 
        if (!empty($data) && 'GET' == $method) $method = 'POST';
 
        switch ($method) {
            case 'POST':
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
                break;
            case 'PUT':
                curl_setopt($curl, CURLOPT_PUT, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
                break;
            case 'DELETE':
                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
                break;
        }
 
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
 
        if (curl_errno($curl)) {
            echo 'Curl error: ' . curl_error($curl);exit;
        }
        curl_close($curl);
 
        return $output;
    }
}

 
// 获取大/小写英文字符
if (!function_exists('getCharacters')) {
    function getCharacters($type = 0)
    {
        if (0 == $type) {
            return ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
        } else {
            return ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
        }
    }
}
 
// 获取远程图片大小
if (!function_exists('getRemoteImageSize')) {
    function getRemoteImageSize($url, &$base64Data = null)
    {
        getFileDataByCurl($url, $base64Data);
 
        return getimagesize('data://image/jpeg;base64,' . $base64Data);
    }
}
 
// 获取文件数据流
if (!function_exists('getFileDataByCurl')) {
    function getFileDataByCurl($url, &$data, $type = 0)
    {
        $ch = curl_init($url);
        // 超时设置
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
 
        // 取前面 1000 个字符 若获取不到数据可适当加大数值
        //curl_setopt($ch, CURLOPT_RANGE, '0-1000');
 
        // 跟踪301跳转
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
 
        // 返回结果
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
        $data = curl_exec($ch);
 
        curl_close($ch);
 
        if (0 == $type) $data = base64_encode($data);
        return $data;
    }
}
 

// 根据图片路径获取图片的尺寸(宽度&高度)
if (!function_exists('getImageSizeByPath')) {
    function getImageSizeByPath($imagePath)
    {
        $flag = 0;
        $sizeInfo = ['width' => 0, 'height' => 0];
        if (!empty($imagePath)) {
            if (false === strpos($imagePath, '_')) $flag = 1;
            else {
                $imagePathArr1 = explode('_', $imagePath);
                if (false === strpos($imagePathArr1[1], '.')) $flag = 1;
                else {
                    $imagePathArr2 = explode('.', $imagePathArr1[1]);
                    if (false === strpos($imagePathArr2[0], 'x')) $flag = 1;
                    else {
                        $imagePathArr3 = explode('x', $imagePathArr2[0]);
                        $sizeInfo['width'] = $imagePathArr3[0];
                        $sizeInfo['height'] = $imagePathArr3[1];
                    }
                }
            }
        }
 
        if (1 == $flag) {
            //list($width, $height) = getimagesize($imagePath);
            $imageSize = getRemoteImageSize($imagePath);
            $sizeInfo['width'] = $imageSize[0];
            $sizeInfo['height'] = $imageSize[1];
        }
 
        return $sizeInfo;
    }
}
//在线图片转base64
 function imgToBase64($img){
    $imageInfo = getimagesize($img);
    $base64 = "" . chunk_split(base64_encode(file_get_contents($img)));
    return 'data:' . $imageInfo['mime'] . ';base64,' . chunk_split(base64_encode(file_get_contents($img)));
 }
// 请求频率控制
if (!function_exists('requestRateControl')) {
    function requestRateControl($key, $seconds = 5)
    {
        $num = Redis::incr($key);
        if (1 == $num) {
            Redis::expire($key, $seconds);
            return true;
        }
        return false;
    }
}
 
/**
 * PHP 非递归实现查询该目录下所有文件
 * @param unknown $dir
 * @return multitype:|multitype:string
 */
function scanfiles($dir) {
    if (! is_dir ( $dir )) return array ();
 
    // 兼容各操作系统
    $dir = rtrim ( str_replace ( '\\', '/', $dir ), '/' ) . '/';
 
    // 栈，默认值为传入的目录
    $dirs = array ( $dir );
 
    // 放置所有文件的容器
    $rt = array ();
    do {
        // 弹栈
        $dir = array_pop ( $dirs );
        // 扫描该目录
        $tmp = scandir ( $dir );
        foreach ( $tmp as $f ) {
 
            // 过滤. ..
            if ($f == '.' || $f == '..')
                continue;
 
            // 组合当前绝对路径
            $path = $dir . $f;
 
            // 如果是目录，压栈。
            if (is_dir ( $path )) {
                array_push ( $dirs, $path . '/' );
            } else if (is_file ( $path )) { // 如果是文件，放入容器中
                $rt [] = $path;
            }
        }
    } while ( $dirs ); // 直到栈中没有目录
    return $rt;
}
 
 
/**
 * 将list_to_tree的树还原成列表
 * @param  array $tree  原来的树
 * @param  string $child 孩子节点的键
 * @param  string $order 排序显示的键，一般是主键 升序排列
 * @param  array  $list  过渡用的中间数组，
 * @return array        返回排过序的列表数组
 * @author yangweijie <yangweijiester@gmail.com>
 */
function tree_to_list($tree, $child = '_child', $order='id', &$list = array()){
    if(is_array($tree)) {
        $refer = array();
        foreach ($tree as $key => $value) {
            $reffer = $value;
            if(isset($reffer[$child])){
                unset($reffer[$child]);
                tree_to_list($value[$child], $child, $order, $list);
            }
            $list[] = $reffer;
        }
        $list = list_sort_by($list, $order, $sortby='asc');
    }
    return $list;
}
 
//PHP过滤所有特殊字符的函数
function match_chinese($chars,$encoding='utf8')
{
    $pattern =($encoding=='utf8')?'/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u':'/[\x80-\xFF]/';
    preg_match_all($pattern,$chars,$result);
    $temp =join('',$result[0]);
    return $temp;
}

//加密编码
function lock_url($txt,$key='fhjkas'){
    $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-="; 
    $nh = rand(0,63); 
    $ch = $chars[$nh];
    $mdKey = md5($key.$ch); 
    $mdKey = substr($mdKey,$nh%8, $nh%8+7); 
    $txt = base64_encode($txt); 
    $tmp = ''; 
    $i=0;$j=0;$k = 0; 
    for ($i=0; $i<strlen($txt); $i++) { 
        $k = $k == strlen($mdKey) ? 0 : $k; 
        $j = ($nh+strpos($chars,$txt[$i])+ord($mdKey[$k++]))%63; 
        $tmp .= $chars[$j]; 
    } 
    return urlencode($ch.$tmp); 
} 
//解密函数 
function unlock_url($txt,$key='fhjkas'){ 
    if(!boolval($txt)){
        return '';
    }
    $txt = urldecode($txt); 
    $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-="; 
    $ch = $txt[0]; 
    $nh = strpos($chars,$ch); 
    $mdKey = md5($key.$ch); 
    $mdKey = substr($mdKey,$nh%8, $nh%8+7); 
    $txt = substr($txt,1); 
    $tmp = ''; 
    $i=0;$j=0; $k = 0; 
    for ($i=0; $i<strlen($txt); $i++) { 
        $k = $k == strlen($mdKey) ? 0 : $k; 
        $j = strpos($chars,$txt[$i])-$nh - ord($mdKey[$k++]); 
        while ($j<0) $j+=63; 
        $tmp .= $chars[$j]; 
    } 
    return base64_decode($tmp); 
} 


/**
 * 随机字符串
 *
 * @param integer $length
 * @param string $type
 * @param integer $convert
 * @return void
 */
function random($length = 6, $type = 'string', $convert = 0)
{
    $config = array('number' => '1234567890',
        'letter' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        'string' => 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789',
        'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
        );

    if (!isset($config[$type])) $type = 'string';
    $string = $config[$type];

    $code = '';
    $strlen = strlen($string) -1;
    for($i = 0; $i < $length; $i++)
    {
        // $code .= $string{mt_rand(0, $strlen)};
        $arr = strToArray($string);
        $code .= $arr[mt_rand(0, $strlen)];
    }
    if (!empty($convert))
    {
        $code = ($convert > 0)? strtoupper($code) : strtolower($code);
    }
    return $code;
}

function filterUa($ua){
    $index = strpos($ua,')');
    $result = substr($ua,0,$index+1);
    return $result;
    // $nets = ['NetType/WIFI','NetType/2G','NetType/3G','NetType/4G','NetType/5G','NetType/4G+'];
    // foreach($nets as $item){
    //     if(strpos($ua,$item)){
    //         $ua = str_replace($item,'-',$ua);
    //     }
    // }
    // return $ua;
}


/**
 * 表单跳转模式
 * $url 地址
 * $data 数据,支持数组或字符串，可留空
 * $target 是否新窗口提交，默认关闭
 */
function jumpPost($url,$data){
	$html = "<form id='form' name='form' action='".$url."' method='post'>";
	if (!empty($data)){
		if (is_array($data)){
			foreach ($data as $key => $val) {
				$html.= "<input type='hidden' name='".$key."' value='".$val."'/>";
			}
		} else {
			$html.= "<input type='hidden' name='value' value='".$data."'/>";
		}
	}
	$html.= "</form>";
	$html.= "<script>document.forms['form'].submit();</script>";
	exit($html);
}


/**
 * 解密
* Decrypt data from a CryptoJS json encoding string
*
* @param mixed $passphrase
* @param mixed $jsonString
* @return mixed
*/
function cryptoJsAesDecrypt( $jsonString,$passphrase='wer85230'){
    $jsondata = json_decode($jsonString, true);
    $salt = hex2bin($jsondata["s"]);
    $ct = base64_decode($jsondata["ct"]);
    $iv  = hex2bin($jsondata["iv"]);
    $concatedPassphrase = $passphrase.$salt;
    $md5 = array();
    $md5[0] = md5($concatedPassphrase, true);
    $result = $md5[0];
    for ($i = 1; $i < 3; $i++) {
        $md5[$i] = md5($md5[$i - 1].$concatedPassphrase, true);
        $result .= $md5[$i];
    }
    $key = substr($result, 0, 32);
    $data = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
    return json_decode($data, true);
}

/**
 * AES 加密 配合cryptojs实现前端js解密
* Encrypt value to a cryptojs compatiable json encoding string
*
* @param mixed $passphrase
* @param mixed $value
* @return string
*/
function cryptoJsAesEncrypt( $value,$passphrase='wer85230'){
    $salt = openssl_random_pseudo_bytes(8);
    $salted = '';
    $dx = '';
    while (strlen($salted) < 48) {
        $dx = md5($dx.$passphrase.$salt, true);
        $salted .= $dx;
    }
    $key = substr($salted, 0, 32);
    $iv  = substr($salted, 32,16);
    $encrypted_data = openssl_encrypt(json_encode($value), 'aes-256-cbc', $key, true, $iv);
    $data = array("ct" => base64_encode($encrypted_data), "iv" => bin2hex($iv), "s" => bin2hex($salt));
    return json_encode($data);
}

/**
 * 支持中文的异或运算,默认key值前端需保持一致
 */
function xor_enc($str,$key='25879') {
    $str = array_values(unpack('n*', iconv('utf-8', 'ucs-2', $str)));
    $key = array_values(unpack('n*', iconv('utf-8', 'ucs-2', $key)));
  
    $crytxt = '';
    $keylen = count($key);
    foreach($str as $i=>$v) 
   {   
      $k = $i % $keylen;
      $crytxt .= pack('n', $v ^ $key[$k]);
    }
    return iconv('ucs-2', 'utf-8', $crytxt); 
}